package com.bruce.asurada.interceptor;

import com.bruce.asurada.config.SsoProperties;
import com.bruce.asurada.service.SsoClientService;
import com.bruce.asurada.common.dto.UserInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * SSO拦截器
 * 负责验证用户登录状态，不处理JWT的生成和解析
 * 
 * @author Bruce
 */
@Slf4j
@Component
public class SsoInterceptor implements HandlerInterceptor {

    @Autowired
    private SsoClientService ssoClientService;

    @Autowired
    private SsoProperties ssoProperties;

    private static final String USER_INFO_ATTR = "userInfo";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.debug("SSO拦截器处理请求: {}", requestURI);

        // 获取令牌
        String token = getAccessToken(request);
        
        if (token == null || token.trim().isEmpty()) {
            log.debug("未找到访问令牌，重定向到登录页面");
            handleUnauthorized(request, response);
            return false;
        }

        try {
            // 调用服务端验证令牌
            UserInfoDto userInfoDto = ssoClientService.verifyToken(token);
            
            if (userInfoDto != null) {
                // 验证成功，将用户信息存储到请求属性中
                request.setAttribute(USER_INFO_ATTR, userInfoDto);
                log.debug("用户 {} 令牌验证成功", userInfoDto.getUsername());
                return true;
            } else {
                log.debug("令牌验证失败");
                handleUnauthorized(request, response);
                return false;
            }
        } catch (Exception e) {
            log.error("令牌验证异常: {}", e.getMessage(), e);
            handleUnauthorized(request, response);
            return false;
        }
    }

    /**
     * 从请求中获取令牌
     */
    private String getAccessToken(HttpServletRequest request) {
        // 从Authorization头获取
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    /**
     * 处理未授权访问
     */
    private void handleUnauthorized(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String requestURI = request.getRequestURI();
        
        // 判断是否为AJAX请求
        String xRequestedWith = request.getHeader("X-Requested-With");
        String accept = request.getHeader("Accept");
        boolean isAjaxRequest = "XMLHttpRequest".equals(xRequestedWith) || 
                               (accept != null && accept.contains("application/json"));
        
        if (isAjaxRequest) {
            // AJAX请求返回JSON格式的401错误
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"message\":\"未登录或登录已过期\",\"data\":null}");
        } else {
            // 普通请求重定向到登录页面
            String loginUrl = ssoProperties.getLoginPage();
            if (loginUrl == null) {
                loginUrl = "/login";
            }
            
            log.debug("重定向到登录页面: {}", loginUrl);
            response.sendRedirect(loginUrl);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理请求属性
        request.removeAttribute(USER_INFO_ATTR);
    }
}